/*
 * This file is a part of the RMI Plugin for Eclipse tutorials.
 * Copyright (C) 2002-7 Genady Beryozkin
 * 
 * You are free to modify this file, as long as you leave
 * the following copyright:
 * 
 * This file is based on the Remote File System example of
 * the RMI Plug-in for Eclipse. The original code is 
 * Copyright (C) 2002-7 Genady Beryozkin
 */
package rmi.filesystem.server;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import rmi.filesystem.common.IRemoteFile;
import rmi.filesystem.common.IRemoteInputStream;


/**
 * Implementation of a remote input stream. It is created by the server
 * using a local file as an argument. 
 * This class extends {@link FileInputStream} only as a convenience,
 * we could extend {@link UnicastRemoteObject} and hold a reference to
 * the {@link FileInputStream} in a field. Since {@link RemoteException} is
 * a subclass of {@link IOException} the method declarations are compatible
 * with their "super" implementations. However, all methods must catch the
 * {@link IOException} returned by the super implementation and wrap it with
 * a {@link RemoteException}.
 * 
 * @see IRemoteFile#getInputStream()
 * @author Genady Beryozkin, rmi-info@genady.net
 */
public class RemoteInputStreamImpl extends FileInputStream implements IRemoteInputStream {

	/**
	 * Create a new RemoteInputStream that reads from a local (server) file.
	 * @see IRemoteFile#getInputStream()
	 */
	
	public RemoteInputStreamImpl(File file) throws RemoteException, FileNotFoundException {
		
		super(file);
		UnicastRemoteObject.exportObject(this);
		
	}

	/* (non-Javadoc)
	 * @see java.io.FileInputStream#read()
	 */
	@Override
	public int read() throws RemoteException {
		try {
			return super.read();
		} catch (IOException e) {
			throw new RemoteException("RemoteInputStreamImpl", e);
		}
	}

	/* (non-Javadoc)
	 * @see demo.rmi.filesystem.common.IRemoteInputStream#read(int)
	 */
	public byte[] readBytes(int count) throws RemoteException {
		try {
			byte[] buf = new byte[count];
			int realCount = super.read(buf);
			if (realCount == -1) {
				return null;
			}
			if (realCount < count) {
				byte[] copy = new byte[realCount];
				System.arraycopy(buf, 0, copy, 0, realCount);
				return copy;
			} else {
				return buf;
			}
		} catch (IOException e) {
			throw new RemoteException("RemoteInputStreamImpl", e);
		}
	}
	
	/* (non-Javadoc)
	 * @see java.io.FileInputStream#available()
	 */
	@Override
	public int available() throws RemoteException {
		try {
			return super.available();
		} catch (IOException e) {
			throw new RemoteException("RemoteInputStreamImpl", e);
		}
	}
	
	/* (non-Javadoc)
	 * @see java.io.InputStream#mark(int)
	 */
	@Override
	public synchronized void mark(int readlimit) {
		super.mark(readlimit);
	}
	
	/* (non-Javadoc)
	 * @see java.io.FileInputStream#close()
	 */
	@Override
	public void close() throws RemoteException {
		try {
			super.close();
		} catch (IOException e) {
			throw new RemoteException("RemoteInputStreamImpl", e);
		}
	}
	
	/* (non-Javadoc)
	 * @see java.io.InputStream#markSupported()
	 */
	@Override
	public boolean markSupported() {
		return super.markSupported();
	}
	
	/* (non-Javadoc)
	 * @see java.io.InputStream#reset()
	 */
	@Override
	public synchronized void reset() throws RemoteException {
		try {
			super.reset();
		} catch (IOException e) {
			throw new RemoteException("RemoteInputStreamImpl", e);
		}
	}
	
	/* (non-Javadoc)
	 * @see java.io.FileInputStream#skip(long)
	 */
	@Override
	public long skip(long n) throws RemoteException {
		try {
			return super.skip(n);
		} catch (IOException e) {
			throw new RemoteException("RemoteInputStreamImpl", e);
		}
	}
}
